home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_08_05 / 8n05107a < prev    next >
Text File  |  1990-04-17  |  7KB  |  250 lines

  1. *****Listing 1*****
  2.  
  3.  
  4.   1: /*
  5.   2:  *  MDBEDIT.C
  6.   3:  *
  7.   4:  *  Program:  Mini-Database
  8.   5:  *  Written by: Leor Zolman
  9.   6:  *  Module:   Edit the Current Database
  10.   7:  */
  11.   8: 
  12.   9: #include <stdio.h>
  13.  10: #include <stdlib.h>
  14.  11: #include <string.h>
  15.  12: #include <ctype.h>
  16.  13: 
  17.  14: #include "mdb.h"
  18.  15: 
  19.  16: static void fix_db(void);
  20.  17: 
  21.  18: #define LIST_RECS 1   /* Edit menu action codes */
  22.  19: #define NEXT      2
  23.  20: #define PREVIOUS  3
  24.  21: #define MODIFY    4
  25.  22: #define NEW       5
  26.  23: #define DELETE    6
  27.  24: #define UNDELETE  7 
  28.  25: #define QUIT      8
  29.  26: #define SELECT    9
  30.  27: #define FIX       10
  31.  28: 
  32.  29: static struct menu_item edit_menu[] =
  33.  30: {
  34.  31:   {LIST_RECS, "List Records"},
  35.  32:   {NEXT, "Go to Next Record"},
  36.  33:   {PREVIOUS, "Go to Previous Record"},
  37.  34:   {MODIFY, "Modify Current Record"},
  38.  35:   {NEW, "Add New Record"},
  39.  36:   {DELETE, "Delete Current Record"},
  40.  37:   {UNDELETE, "Un-Delete Current Record"},
  41.  38:   {SELECT, "Select Record (by Record Number)"},
  42.  39:   {FIX, "Fix Up Database"},
  43.  40:   {QUIT, "Return to Main Menu"},
  44.  41:   {NULL}
  45.  42: };
  46.  43: 
  47.  44: /*
  48.  45:  * Function:    edit_db
  49.  46:  * Purpose:     Perform operations on current Database
  50.  47:  * Parameter:   Database Name
  51.  48:  * Return Value:  None
  52.  49:  */
  53.  50: 
  54.  51: void edit_db(char *db_name)
  55.  52: {
  56.  53:   int cur_rec = 0;  /* current record number */
  57.  54:   struct record *rp;  /* ptr to current record */
  58.  55:   char buf[150];
  59.  56:   int i;
  60.  57:   
  61.  58:   while (1)
  62.  59:   {
  63.  60:     rp = RECS[cur_rec];
  64.  61:     printf("\nDatabase: %s\n", db_name);
  65.  62:     if (n_recs)
  66.  63:     {
  67.  64:       printf("Current Record is #%d", cur_rec);
  68.  65:       if (!rp->active)
  69.  66:         printf(" (Deleted)");
  70.  67:       printf(":\n");
  71.  68: 
  72.  69:       printf("Name:   %s %s\n", rp->first, rp->last);
  73.  70:       printf("ID#:    %ld\n", rp->id);
  74.  71:       printf("Age:    %d\n", rp->age);
  75.  72:       printf("Gender: %c\n", rp->gender);
  76.  73:       printf("Salary: $%.2f\n", rp->salary);
  77.  74:     }
  78.  75:     
  79.  76:     switch(do_menu(edit_menu, "Edit Menu"))
  80.  77:     {
  81.  78:       case LIST_RECS:
  82.  79:         for (i = 0; i < n_recs; i++)
  83.  80:           printf("%4d: %s%s\n", i, RECS[i]->last,
  84.  81:             RECS[i]->active ? "" : " (Deleted)");
  85.  82:         printf("Press RETURN to continue:");
  86.  83:         gets(buf);
  87.  84:         break;
  88.  85:           
  89.  86:       case NEXT:      /* find next active record: */
  90.  87:         for (i = cur_rec + 1; i < n_recs; i++)
  91.  88:           if (RECS[i]->active) /* skip inactives */
  92.  89:             break;
  93.  90:         if (i == n_recs)       /* over the top? */
  94.  91:         {
  95.  92:           printf("\aAt end of file.\n");
  96.  93:           break;
  97.  94:         }
  98.  95:         cur_rec = i;
  99.  96:         break;
  100.  97:         
  101.  98:       case PREVIOUS:  /* find previous active record: */
  102.  99:         for (i = cur_rec - 1; i >= 0; i--)
  103. 100:           if (RECS[i]->active) /* skip inactives */
  104. 101:             break;
  105. 102:         if (i < 0)       /* "under the bottom"? */
  106. 103:         {
  107. 104:           printf("\aAt beginning of file.\n");
  108. 105:           break;
  109. 106:         }
  110. 107:         cur_rec = i;
  111. 108:         break;
  112. 109:                 
  113. 110:       case NEW:
  114. 111:         if (n_recs+1 > max_recs)
  115. 112:         {
  116. 113:           printf("Maximum # of records ");
  117. 114:           printf("(%d) reached.\n", max_recs);
  118. 115:           break;
  119. 116:         }
  120. 117: 
  121. 118:         if ((rp = alloc_rec()) == NULL)
  122. 119:         {
  123. 120:           printf("Out of memory. Try Fixing ");
  124. 121:           printf("Database first...\n");
  125. 122:           break;
  126. 123:         }
  127. 124:                    /* make new record current:  */
  128. 125:         cur_rec = n_recs++;
  129. 126:         RECS[cur_rec] = rp;
  130. 127:         rp->active = TRUE;
  131. 128: 
  132. 129:         strcpy(rp->last,""); /* initialize the record */
  133. 130:         strcpy(rp->first,"");
  134. 131:         rp->id = 0;
  135. 132:         rp->age = 0;
  136. 133:         rp->gender = ' ';
  137. 134:         rp->salary = 0.;  /*  fall through to MODIFY  */
  138. 135:         
  139. 136:       case MODIFY:
  140. 137:         printf("Last Name [%s]: ", rp->last);
  141. 138:         if (strlen(gets(buf)) > 0)
  142. 139:           strcpy(rp->last, buf);
  143. 140:           
  144. 141:         printf("First Name [%s]: ", rp->first);
  145. 142:         if (strlen(gets(buf)) > 0)
  146. 143:           strcpy(rp->first, buf);
  147. 144: 
  148. 145:         printf("ID# [%ld]: ", rp->id);
  149. 146:         if (strlen(gets(buf)) > 0)
  150. 147:           rp->id = atol(buf);
  151. 148:         
  152. 149:         printf("Age [%d] ", rp->age);
  153. 150:         if (strlen(gets(buf)) > 0)
  154. 151:           rp->age = atoi(buf);
  155. 152:         
  156. 153:         printf("Gender [%c]: ", rp->gender);
  157. 154:         if (strlen(gets(buf)) > 0)
  158. 155:           rp->gender = toupper(*buf);
  159. 156:         
  160. 157:         printf("Salary [%.2f]: ", rp->salary);
  161. 158:         if (strlen(gets(buf)) > 0)
  162. 159:           rp->salary = (float) atof(buf);
  163. 160:         break;
  164. 161:       
  165. 162:       case DELETE:
  166. 163:         if (!rp->active)
  167. 164:         {
  168. 165:           printf("Record is already deleted.\n");
  169. 166:           break;
  170. 167:         }
  171. 168:         printf("Press 'y' to delete record,\n");
  172. 169:         printf("anything else to abort: ");
  173. 170:         gets(buf);
  174. 171:         if (tolower(*buf) == 'y')
  175. 172:           rp->active = FALSE;
  176. 173:         break;
  177. 174:         
  178. 175:       case UNDELETE:
  179. 176:         if (rp->active)
  180. 177:         {
  181. 178:           printf("Record is not deleted.\n");
  182. 179:           break;
  183. 180:         }
  184. 181:         rp->active = TRUE;
  185. 182:         printf("Record restored.\n");
  186. 183:         break;
  187. 184: 
  188. 185:       case SELECT:
  189. 186:         printf("Enter new record number: ");
  190. 187:         i = atoi(gets(buf));
  191. 188:         if (i < 0 || i > n_recs)
  192. 189:         {
  193. 190:           printf("Record # out of range.\n");
  194. 191:           break;
  195. 192:         }
  196. 193:         cur_rec = i;
  197. 194:         break;
  198. 195:         
  199. 196:       case FIX:
  200. 197:         fix_db();   /* clean up database  */
  201. 198:         break;
  202. 199:             
  203. 200:       case QUIT:
  204. 201:         return;
  205. 202:     }
  206. 203:   }
  207. 204: }
  208. 205:   
  209. 206: /*
  210. 207:  * Function:     fix_db
  211. 208:  * Purpose:      Purge deleted records, sort Database
  212. 209:  * Parameters:   None
  213. 210:  * Return Value: None
  214. 211:  */
  215. 212: 
  216. 213: static  int compar( struct record **p1,
  217. 214:                     struct record **p2);
  218. 215: 
  219. 216: static void fix_db()    /* File Fix module */
  220. 217: {
  221. 218:   int i, new_n_recs;
  222. 219:   
  223. 220:   for (i = 0, new_n_recs = 0; i < n_recs; i++)
  224. 221:   {
  225. 222:     RECS[new_n_recs] = RECS[i];
  226. 223:     if (RECS[i]->active)
  227. 224:       new_n_recs++;
  228. 225:     else
  229. 226:       free(RECS[i]);
  230. 227:   }
  231. 228: 
  232. 229:   n_recs = new_n_recs;
  233. 230:   qsort(RECS, new_n_recs,
  234. 231:           sizeof(struct record *), compar);
  235. 232: }
  236. 233: 
  237. 234: /*
  238. 235:  * Function:    compar
  239. 236:  * Purpose:     Comparison function for qsort(), 
  240. 237:  *                sorting simply on last name
  241. 238:  * Parameters:  Two pointers to record pointers
  242. 239:  * Return Value:  As per strcmp()
  243. 240:  */
  244. 241: 
  245. 242: static int compar(struct record **p1,
  246. 243:                   struct record **p2)
  247. 244: {
  248. 245:   return strcmp((*p1)->last, (*p2)->last);
  249. 246: }
  250.